
/*
 * Copyright 2016 Hani Al Momani
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package hani.momanii.supernova_emoji_library.Handler;

import hani.momanii.supernova_emoji_library.ResourceTable;
import hani.momanii.supernova_emoji_library.emoji.*;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.app.Context;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.media.image.PixelMap;
import ohos.multimodalinput.event.TouchEvent;

import java.util.Arrays;

public class EmojiconsPopup extends DirectionalLayout implements PageSlider.PageChangedListener, EmojiconRecents {
    private final DependentLayout view;
    private final Context mContext;
    private PageSlider emojisPager;
    private Component[] mEmojiTabs;
    private EmojiconRecentsManager mRecentsManager;
    private int tabsColor = Color.getIntColor("#DCE1E2");
    private int backgroundColor = Color.getIntColor("#E6EBEF");
    private int mEmojiTabLastSelectedIndex = -1;
    private Component tempComponent = null;
    private PixelMap tempSouse = null;
    private int mWidth;
    private int mHeight;
    private final EmojiconTextField[] mTextField;
    private boolean isDelete = false;
    private final MyRun myRun = new MyRun();

    /**
     * 构造
     *
     * @param context 上下文
     * @param width 宽
     * @param height 高
     * @param textFields 输入框
     */
    public EmojiconsPopup(Context context, int width, int height, EmojiconTextField... textFields) {
        super(context);
        this.mContext = context;
        this.mTextField = textFields;
        this.mWidth = width;
        this.mHeight = height;
        view = (DependentLayout) LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_emojicons, null, true);
        view.setHeight(height);
        view.setWidth(width);
        setAlignment(LayoutAlignment.BOTTOM);
        setCursorVisible(textFields);
        addComponent(createCustomView());
        setVisibility(VERTICAL);
    }

    private void setCursorVisible(EmojiconTextField[] textFields) {
        for (EmojiconTextField textField : textFields) {
            if ("1".equals(textField.getTag())) {
                textField.setFocusable(Component.FOCUS_ENABLE);
                textField.setEnabled(true);
                textField.requestFocus();
                textField.setTextCursorVisible(true);
            }
        }
    }

    /**
     * 子视图
     *
     * @return conponent
     */
    public Component createCustomView() {
        emojisPager = (PageSlider) view.findComponentById(ResourceTable.Id_emojis_pager);
        DirectionalLayout tabs = (DirectionalLayout) view.findComponentById(ResourceTable.Id_emojis_tab);
        EmojiconRecents recents = this;
        emojisPager.addPageChangedListener(this);
        EmojisPageProvider mEmojisAdapter = new EmojisPageProvider(Arrays.asList(new EmojiconRecentsListContainer(mContext, null, recents, this, mTextField),
                new EmojiconListContainer(mContext, People.DATA, recents, this, mTextField),
                new EmojiconListContainer(mContext, Nature.DATA, recents, this, mTextField),
                new EmojiconListContainer(mContext, Food.DATA, recents, this, mTextField),
                new EmojiconListContainer(mContext, Sport.DATA, recents, this, mTextField),
                new EmojiconListContainer(mContext, Cars.DATA, recents, this, mTextField),
                new EmojiconListContainer(mContext, Electr.DATA, recents, this, mTextField),
                new EmojiconListContainer(mContext, Symbols.DATA, recents, this, mTextField)
        ));
        emojisPager.setProvider(mEmojisAdapter);
        mEmojiTabs = new Component[8];

        mEmojiTabs[0] = view.findComponentById(ResourceTable.Id_emojis_tab_0_recents);
        mEmojiTabs[1] = view.findComponentById(ResourceTable.Id_emojis_tab_1_people);
        mEmojiTabs[2] = view.findComponentById(ResourceTable.Id_emojis_tab_2_nature);
        mEmojiTabs[3] = view.findComponentById(ResourceTable.Id_emojis_tab_3_food);
        mEmojiTabs[4] = view.findComponentById(ResourceTable.Id_emojis_tab_4_sport);
        mEmojiTabs[5] = view.findComponentById(ResourceTable.Id_emojis_tab_5_cars);
        mEmojiTabs[6] = view.findComponentById(ResourceTable.Id_emojis_tab_6_elec);
        mEmojiTabs[7] = view.findComponentById(ResourceTable.Id_emojis_tab_7_sym);
        for (int index = 0; index < mEmojiTabs.length; index++) {
            final int position = index;
            mEmojiTabs[index].setClickedListener(v -> {
                emojisPager.setCurrentPage(position);
                setBg(position);
            });
        }

        ShapeElement pageElement = new ShapeElement();
        pageElement.setRgbColor(RgbColor.fromArgbInt(backgroundColor));
        emojisPager.setBackground(pageElement);

        ShapeElement tabsElement = new ShapeElement();
        tabsElement.setRgbColor(RgbColor.fromArgbInt(tabsColor));
        tabs.setBackground(tabsElement);

        Component back = view.findComponentById(ResourceTable.Id_emojis_backspace);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(backgroundColor));
        shapeElement.setShape(ShapeElement.RECTANGLE);
        back.setBackground(pageElement);
        setOnEmojiconBackspaceClickedListener(back);

        mRecentsManager = EmojiconRecentsManager.getInstance(view.getContext());
        int page = mRecentsManager.getRecentPage();
        if (page == 0 && mRecentsManager.size() == 0) {
            page = 1;
        }

        if (page == 0) {
            emojisPager.setCurrentPage(page);
        } else {
            emojisPager.setCurrentPage(page, false);
        }

        setBg(page);
        return view;
    }

    /**
     * 设置颜色
     *
     * @param tabscolor The color of tabs background
     * @param backgroundcolor The color of emoji background
     */
    public void setColors(final int tabscolor, final int backgroundcolor) {
        this.backgroundColor = backgroundcolor;
        this.tabsColor = tabscolor;
    }

    private void setBg(int position) {
        switch (position) {
            case 0:
                setImg(mEmojiTabs[0], ResourceTable.Media_emoji_recent_focus);
                break;
            case 1:
                setImg(mEmojiTabs[1], ResourceTable.Media_emoji_people_focus);
                break;
            case 2:
                setImg(mEmojiTabs[2], ResourceTable.Media_emoji_nature_focus);
                break;
            case 3:
                setImg(mEmojiTabs[3], ResourceTable.Media_emoji_food_focus);
                break;
            case 4:
                setImg(mEmojiTabs[4], ResourceTable.Media_emoji_activity_focus);
                break;
            case 5:
                setImg(mEmojiTabs[5], ResourceTable.Media_emoji_travel_focus);
                break;
            case 6:
                setImg(mEmojiTabs[6], ResourceTable.Media_emoji_objects_focus);
                break;
            case 7:
                setImg(mEmojiTabs[7], ResourceTable.Media_emoji_symbols_focus);
                break;
        }
    }

    private void setImg(Component component, int souse) {
        if (tempComponent != null && tempSouse != null) {
            ((Image) tempComponent).setPixelMap(tempSouse);
        }
        Image mEmoji = (Image) component;
        tempSouse = mEmoji.getPixelMap();
        mEmoji.setPixelMap(souse);
        tempComponent = component;
    }

    @Override
    public void onPageSliding(int i, float v, int i1) {
    }

    @Override
    public void onPageSlideStateChanged(int i) {
    }

    @Override
    public void onPageChosen(int index) {
        if (mEmojiTabLastSelectedIndex == index) {
            return;
        }
        switch (index) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                if (mEmojiTabLastSelectedIndex >= 0 && mEmojiTabLastSelectedIndex < mEmojiTabs.length) {
                    mEmojiTabs[mEmojiTabLastSelectedIndex].setSelected(false);
                }
                mEmojiTabs[index].setSelected(true);
                mEmojiTabLastSelectedIndex = index;
                mRecentsManager.setRecentPage(index);
                setBg(mEmojiTabLastSelectedIndex);
                break;
        }
    }

    @Override
    public void addRecentEmoji(Context context, Emojicon emojicon, EmojiconTextField... textField) {
        EmojiconRecentsListContainer fragment = ((EmojisPageProvider) emojisPager.getProvider()).getRecentFragment();
        fragment.addRecentEmoji(context, emojicon, textField);
        for (EmojiconTextField field : textField) {
            if (field.getTag().toString().equals("1")) {
                field.insert(emojicon.getEmoji());
                return;
            }
        }
    }

    /**
     * 隐藏
     */
    public void hide() {
        setVisibility(HIDE);
    }

    /**
     * Use this function to show the emoji popup.
     * NOTE: Since, the soft keyboard sizes are variable on different devices, the
     * library needs you to open the soft keyboard atleast once before calling this function.
     * If that is not possible see showAtBottomPending() function.
     */
    public void show() {
        mEmojiTabs[1].setSelected(true);
        emojisPager.setCurrentPage(1);
        onPageChosen(1);
        setVisibility(Component.VISIBLE);
    }

    /**
     * 销毁
     */
    public void dismiss() {
        setVisibility(Component.HIDE);
    }

    /**
     * 设置大小
     *
     * @param width 宽
     * @param height 高
     */
    public void setSize(int width, int height) {
        this.mWidth = width;
        this.mHeight = height;
        view.setHeight(mWidth);
        view.setWidth(mHeight);
    }

    /**
     * 是否使用软键盘
     *
     * @param isUseSystemDefault 标记
     */
    public void updateUseSystemDefault(boolean isUseSystemDefault) {
    }

    /**
     * 显示在下方
     */
    public void showAtBottom() {
        show();
    }

    /**
     * 显示在下方
     */
    public void showAtBottomPending() {
        showAtBottom();
    }

    public Boolean isKeyBoardOpen() {
        return getVisibility() == VISIBLE;
    }

    /**
     * 设置键盘尺寸
     *
     * @param width 宽
     * @param height 高
     */
    public void setSizeForSoftKeyboard(int width, int height) {
        this.mWidth = width;
        this.mHeight = height;
        view.setHeight(mWidth);
        view.setWidth(mHeight);
    }

    /**
     * 设置监听
     *
     * @param context 上下文
     * @param emojicon 对象
     * @param editTexts 输入框
     */
    public void setOnEmojiconClickedListener(Context context, Emojicon emojicon, EmojiconTextField... editTexts) {
        addRecentEmoji(context, emojicon, editTexts);
    }

    /**
     * 设置监听
     *
     * @param back Component
     */
    public void setOnEmojiconBackspaceClickedListener(Component back) {
        back.setClickedListener(component -> {
            isDelete = true;
            for (EmojiconTextField textField : mTextField) {
                if (textField.getTag().toString().equals("1")) {
                    textField.delete(1, true);
                    return;
                }
            }
        });
        back.setLongClickedListener(component -> {
            isDelete = true;
            longClick();
        });
        back.setTouchEventListener((component, touchEvent) -> {
            switch (touchEvent.getAction()) {
                case TouchEvent.PRIMARY_POINT_DOWN:
                    return true;
                case TouchEvent.PRIMARY_POINT_UP:
                    isDelete = false;
                    break;
                default:
                    break;
            }
            return false;
        });
    }

    private void longClick() {
        TaskDispatcher taskDispatcher = mContext.getUITaskDispatcher();
        taskDispatcher.delayDispatch(myRun, 300);
    }

    private class MyRun implements Runnable {
        @Override
        public void run() {
            if (isDelete) {
                for (EmojiconTextField textField : mTextField) {
                    if (textField.getTag().toString().equals("1")) {
                        textField.delete(1, true);
                        break;
                    }
                }
                longClick();
            }
        }
    }
}
